home *** CD-ROM | disk | FTP | other *** search
- From: ukma!david (David Herron, NPR Lover)
- Subject: A BASIC interpretor (Part 2 of 4)
- Newsgroups: mod.sources
- Approved: john@genrad.UUCP
-
- Mod.sources: Volume 2, Issue 24
- Submitted by: ukma!david (David Herron)
-
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # newbs/bsdefs.c
- # newbs/bsdefs.h
- # newbs/bsgram.y
- # newbs/bslash.c
- # newbs/bslib.c
- # newbs/getplace.c
- # newbs/gvadr.c
- # newbs/makefile
- # newbs/makefile.old
- # newbs/mkop.c
- # newbs/mkop.sh
- # newbs/mksop.c
- # newbs/num_ins.c
- # newbs/op2.c
- # newbs/operat.c
- # newbs/scon_in.c
- # This archive created: Tue Jul 30 13:02:34 1985
- export PATH; PATH=/bin:$PATH
- if test ! -d 'newbs'
- then
- echo shar: creating directory "'newbs'"
- mkdir 'newbs'
- fi
- echo shar: extracting "'newbs/bsdefs.c'" '(1128 characters)'
- if test -f 'newbs/bsdefs.c'
- then
- echo shar: will not over-write existing file "'newbs/bsdefs.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'newbs/bsdefs.c'
- /* bsdefs.c -- Actual definitions of all the variables.
- *
- * bsdefs.h only has the "extern's" of the things declared in here.
- */
-
- #include "bsdefs.h"
-
-
- /* Initial stuff for line number table.
- *
- * The line number table is a singly-linked list. The head is "firstline",
- * and the tail is "lastline". The proper way to check for the end of the
- * list is to compare it to LASTLINE. Lastline points to itself in case
- * I forget and code something differently (it also neatly ties up the end
- * of the list).
- */
-
- #define LASTLINE (struct line *)(&lastline)
-
- struct line lastline = { &lastline,0077777,"",_nulline };
- struct line firstline = { &lastline,0,"",_nulline };
- struct line *curline = LASTLINE;
-
-
- /* Initial stuff for data statements.
- *
- * "dlist[]" holds pointers to lines that have data on them. It is initialized
- * in M_FIXUP. "dlp" used to allocate entries from dlist[], it points to the
- * first free entry. "dlindx" points within the current data line to the next
- * data item.
- * "dtype" indicates the data type for the last data item.
- */
-
- struct line *dlist[DLSIZ];
- int dlp = 0,dlindx = 0, dtype = 0;
-
- SHAR_EOF
- if test 1128 -ne "`wc -c < 'newbs/bsdefs.c'`"
- then
- echo shar: error transmitting "'newbs/bsdefs.c'" '(should have been 1128 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'newbs/bsdefs.h'" '(4648 characters)'
- if test -f 'newbs/bsdefs.h'
- then
- echo shar: will not over-write existing file "'newbs/bsdefs.h'"
- else
- sed 's/^X//' << \SHAR_EOF > 'newbs/bsdefs.h'
- /* bsdefs.h -- definition file for bs.
- */
-
- #include <stdio.h>
- #include <ctype.h>
-
- /* 'Machine' status */
- extern int status;
- #define M_COMPILE (1<<0)
- #define M_EXECUTE (1<<1)
- #define M_INPUT (1<<2)
- #define M_FIXUP (1<<3)
- #define M_READ (1<<4)
-
- #define XMODE (M_COMPILE|M_EXECUTE|M_INPUT|M_FIXUP|M_READ)
-
-
- /* line table. */
- #define LASTLINE (struct line *)(&lastline)
-
- struct line {
- struct line *nextline; /* next entry in list. */
- int lnum; /* its' number */
- int (*list)(); /* its' definition */
- char *text; /* the original definition */
- };
-
- extern struct line firstline,lastline,*curline;
-
-
- /* Variable types */
- #define Q_NRM 0 /* nice, ordinary variable */
- #define Q_ARY 1 /* array */
- #define Q_BF 2 /* builtin-function */
- #define Q_UFL 3 /* long user function */
- #define Q_UFS 4 /* short user function */
-
- /* in type part, a zero value is an undefined type. */
- #define T_INT (1<<6)
- #define T_CHR (2<<6)
- #define T_DBL (3<<6)
- #define T_LBL (4<<6)
-
- #define T_QMASK 037 /* lower 5 bits for type qualifier */
- #define T_TMASK (T_INT|T_CHR|T_DBL|T_LBL)
-
- /* variable table */
- #define VLSIZ 150
-
- struct label {
- char *name; /* what do we call it by. */
- int (*where)(); /* and where does it live */
- };
- /* For arrays, storage of them is defined as follows:
- *
- * 1st item: number of dimensions in array <NDIMS>.
- * next <NDIMS> items: size of each dimension.
- * rest of items: the actual values.
- *
- * Until we can support varrying sized arrays this is the setup:
- *
- * 1,10,x0,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10
- *
- * for a total size of 13 items.
- */
- union value {
- long ival; /* T_INT */
- double rval; /* T_DBL */
- char *sval; /* T_CHR */
- struct label lval; /* T_LBL */
- struct line *locval; /* for pushing line# list entries */
- union value *arval; /* any+Q_ARY */
- struct dictnode *vpval; /* for use when pushing variable pointers */
- union value *plval; /* for use when pushing pointers to a value */
- };
-
- struct dictnode { /* format of vlist entry */
- struct dictnode *father,*daughter; /* doubly-linked list. */
- char *name; /* name of entry. */
- int type_of_value; /* its type. */
- union value val; /* and its value */
- };
-
- extern struct dictnode *dicthead,*dictail,*curvp;
-
- /* '_' Function table */
- extern
- _print(), _goto(), _if(), _else(),
- _for(), _next(), _read(), _data(),
- _dsep(), _spop(), _pop(), _stop(),
- _end(), _dlabel(), _rlabel(), _contin(),
- _leave(), _enter(), _exitlp(), _iadd(),
- _isub(), _imult(), _idiv(), _imod(),
- _comma(), _radd(), _rsub(), _rmult(),
- _rdiv(), _scolon(), _gosub(), _return(),
- _not(), _ieq(), _req(), _seq(),
- _ineq(), _rneq(), _sneq(), _ileq(),
- _rleq(), _sleq(), _ilt(), _rlt(),
- _slt(), _igeq(), _rgeq(), _sgeq(),
- _igt(), _rgt(), _sgt(), _or(),
- _and(), _itoa(), _rtoa(), _itor(),
- _rtoi(), _pushstate(), _popstate(), _scon(),
- _rcon(), _icon(), _val(), _store(),
- _var();
-
- /*
- * Data table.
- * Array of pointers into llist.
- * Each is a line which has data.
- */
- #define DLSIZ 100
- extern struct line *dlist[]; /* actual table, number of elems. is DLSIZ */
- extern int dlp; /* index into dlist for current line of data */
- extern int dlindx; /* index into current line for current data item. */
- extern int dtype; /* in M_READ, operators set this to the type of
- * their operation. When the expression is done
- * executing, this variable will indicate its type.
- */
-
- /* error routines */
- extern int ULerror();
- extern int STerror();
- extern int FNerror();
- extern int ODerror();
- extern int BDerror();
- extern int VTerror();
-
-
- /*
- * unions for storing data types in the code list
- *
- * Used to convert from a double (for instance) into "int" sized chunks
- * for the purpose of manipulating instances of them in code lists.
- */
-
-
- union doni {
- double d_in_doni;
- int i_in_doni[sizeof(double)/sizeof(int)];
- };
- union loni {
- long l_in_loni;
- int i_in_loni[sizeof(long)/sizeof(int)];
- };
- union voni {
- union value v_in_voni;
- int i_in_voni[sizeof(union value)/sizeof(int)];
- };
-
-
- /* miscellaneous definitions. */
-
- #define STKSIZ 500
- extern union value stack[];
- extern int stackp;
- extern int push();
- extern union value pop();
-
- #define CSTKSIZ 5
- #define BFSIZ 200 /* input buffer */
- extern char pbbuf[]; /* unput() buffer */
- extern char ibuf[];
- extern int iptr,pbptr;
- extern char input();
- extern rdlin(),unput();
-
- extern blcpy();
-
- extern char bslash();
- extern char *scon_in();
- extern int num_in();
-
- extern char *myalloc();
- extern union value *getplace();
- extern struct line *gllentry();
-
- extern FILE *bsin;
-
- extern int dbg; /* debugging flag. */
- extern long atol();
- extern double atof();
- SHAR_EOF
- if test 4648 -ne "`wc -c < 'newbs/bsdefs.h'`"
- then
- echo shar: error transmitting "'newbs/bsdefs.h'" '(should have been 4648 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'newbs/bsgram.y'" '(8891 characters)'
- if test -f 'newbs/bsgram.y'
- then
- echo shar: will not over-write existing file "'newbs/bsgram.y'"
- else
- sed 's/^X//' << \SHAR_EOF > 'newbs/bsgram.y'
- /* bsgram.y -- grammer specification for bs.
- */
- %{
- #include "bsdefs.h"
-
- char *p; /* the generic pointer */
- int i; /* the generic counter */
- int (*l[300])(); /* array to generate the code list into. */
- int lp; /* pointer to current spot in l[] */
-
- struct stk {
- int stack[40];
- int stkp;
- };
-
- struct stk ifstk,whstk,forstk,repstk,lpstk;
- int gomax=0, ifmax=0, whmax=0, formax=0, repmax=0, lpmax=0;
-
- extern char *yytext;
- extern char *bsyysval;
- extern int yyleng;
- %}
-
- %term EQUAL NEQ LE LT GE WHILE
- %term GT OR AND NOT RET REPEAT
- %term IF THEN ELSE GOTO GOSUB UNTIL
- %term STOP END INTEGER REAL SCONST ELIHW
- %term LET SWORD PRINT INPUT DATA CFOR
- %term FOR TO STEP READ WRITE NEXT
- %term DEFINE LFUN SFUN FDEF SYMBOL DIM
- %term VALUE IWORD RWORD ROFC LOOP EXITIF
- %term ITOR RTOI ITOA RTOA LEAVE CONTINUE
- %term POOL
-
- %left ',' ';'
- %right '='
- %nonassoc OR AND
- %nonassoc LE LT GE GT EQUAL NEQ
- %left '+' '-'
- %left '*' '/' '%'
- %left UNARY
- %left '('
-
-
- %start lines
-
- %%
-
- lines : /* empty */
- | lines line
- ;
-
- line : lnum stat '\n'
- { printf("\n"); }
- | '\n'
- ;
-
- lnum : INTEGER
- { bundle(2,_line,atoi($1); }
- ;
-
- stat : LET let_xpr
- | let_xpr
- | PRINT pe
- { bundle(1,_print); }
- | GOTO INTEGER
- {
- sprintf(s,"LN%s",$2);
- bundle(4,_rlabel,gvadr(s,T_LBL),_goto,0);
- }
- | GOSUB INTEGER
- {
- sprintf(s,"LN%s",$2);
- bundle(4,_rlabel,gvadr(s,T_LBL),_gosub,0);
- }
- | LEAVE
- { bundle(2,_leave,0); }
- | CONTINUE
- { bundle(2,_contin,0); }
- | RET
- { bundle(1,_return); }
- | IF bexpr
- {
- lpush(&ifstk,ifmax);
- sprintf(s,"IF%d",ifmax);
- bundle(4,_rlabel,gvadr(s,T_LBL),_if,0);
- ifmax += 2;
- }
- THEN stat
- {
- i = ltop(&ifstk);
- sprintf(s,"IF%d",i+1);
- bundle(4,_rlabel,gvadr(s,T_LBL),_goto,0);
- }
- if_else
- | INPUT
- { bundle(2,_pushstate,M_INPUT); }
- var_lst
- { bundle(1,_popstate); }
- | STOP
- { bundle(1,_stop); }
- | END
- { bundle(1,_end); }
- | FOR nvar '=' rexpr TO rexpr for_step
- {
- lpush(&forstk,formax);
- sprintf(s,"FOR%d",formax+2);
- bundle(2,_rlabel,gvadr(s,T_LBL));
- sprintf(s,"FOR%d",formax+1);
- bundle(3,_rlabel,gvadr(s,T_LBL),_enter);
- sprintf(s,"FOR%d",formax+1);
- bundle(5,_icon,(long)0,_rlabel,gvadr(s,T_LBL));
- sprintf(s,"FOR%d",formax);
- bundle(4,_dlabel,gvadr(s,T_LBL),_for,0);
- formax += 3;
- }
- | NEXT
- {
- i = ltop(&forstk);
- sprintf(s,"FOR%d",i+2);
- bundle(2,_dlabel,gvadr(s,T_LBL));
- }
- nvar
- {
- i = lpop(&forstk);
- sprintf(s,"FOR%d",i);
- bundle(5,_next,_rlabel,gvadr(s,T_LBL),_goto,0);
- sprintf(s,"FOR%d",i+1);
- bundle(3,_dlabel,gvadr(s,T_LBL),_exitlp);
- }
- | READ
- { bundle(2,_pushstate,M_READ); }
- var_lst
- { bundle(1,_popstate); }
- | DATA
- { bundle(2,_data,0); }
- data_lst
- | LOOP
- {
- lpush(&lpstk,lpmax);
- sprintf(s,"LP%d",lpmax+2);
- bundle(2,_rlabel,gvadr(s,T_LBL));
- sprintf(s,"LP%d",lpmax+1);
- bundle(3,_rlabel,gvadr(s,T_LBL),_enter);
- sprintf(s,"LP%d",lpmax);
- bundle(2,_dlabel,gvadr(s,T_LBL));
- lpmax += 3;
- }
- | EXITIF bexpr
- {
- i = ltop(&lpstk);
- sprintf(s,"LP%d",i+1);
- bundle(5,_not,_rlabel,gvadr(s,T_LBL),_if,0);
- }
- | POOL
- {
- i = lpop(&lpstk);
- sprintf(s,"LP%d",i+2);
- bundle(2,_dlabel,gvadr(s,T_LBL));
- sprintf(s,"LP%d",i);
- bundle(4,_rlabel,gvadr(s,T_LBL),_goto,0);
- sprintf(s,"LP%d",i+1);
- bundle(3,_dlabel,gvadr(s,T_LBL),_exitlp);
- }
- | WHILE
- {
- lpush(&whstk,whmax);
- sprintf(s,"WH%d",whmax+2);
- bundle(2,_rlabel,gvadr(s,T_LBL));
- sprintf(s,"WH%d",whmax+1);
- bundle(3,_rlabel,gvadr(s,T_LBL),_enter);
- sprintf(s,"WH%d",whmax);
- bundle(2,_rlabel,gvadr(s,T_LBL));
- whmax += 3;
- }
- bexpr
- {
- i = ltop(&whstk);
- sprintf(s,"WH%d",i+1);
- bundle(4,_rlabel,gvadr(s,T+LBL),_if,0);
- }
- | ELIHW
- {
- i = lpop(&whstk);
- sprintf(s,"WH%d",i+2);
- bundle(2,_dlabel,gvadr(s,T_LBL));
- sprintf(s,"WH%d",i)
- bundle(4,_rlabel,gvadr(s,T_LBL),_goto,0);
- sprintf(s,"WH%d",i+1);
- bundle(3,_dlabel,gvadr(s,T_LBL),_exitlp);
- }
- | REPEAT
- {
- lpush(&repstk,repmax);
- sprintf(s,"REP%d",repmax+1);
- bundle(2,_rlabel,gvadr(s,T_LBL));
- sprintf(s,"REP%d",repmax+2);
- bundle(3,_rlabel,gvadr(s,T_LBL),_enter);
- sprintf(s,"REP%d",repmax);
- bundle(2,_dlabel,gvadr(s,T_LBL));
- repmax += 3;
- }
- | UNTIL
- {
- i = ltop(&repstk);
- sprintf(s,"REP%d",i+1);
- bundle(2,_dlabel,gvadr(s,T_LBL));
- }
- bexpr
- {
- i = lpop(&repstk);
- sprintf(s,"REP%d",i);
- bundle(5,_not,_rlabel,gvadr(s,T_LBL),_if,0);
- sprintf(s,"REP%d",i+2);
- bundle(3,_dlabel,gvadr(s,T_LBL),_exitlp);
- }
- ;
-
- nvar : ivar
- | rvar
- ;
-
- let_xpr : ivar '=' rexpr
- { bundle(4,_rtoi,_store,T_DBL,_pop); }
- | rvar '=' rexpr
- { bundle(3,_store,T_DBL,_pop); }
- | svar '=' sexpr
- { bundle(3,_store,T_CHR,spop); }
- ;
-
- data_lst : rexpr
- { bundle(2,_dsep,0); }
- | sexpr
- { bundle(1,_dsep); }
- | data_lst ',' rexpr
- { bundle(1,_dsep); }
- | data_lst ',' sexpr
- { bundle(1,_dsep); }
- ;
-
- ind_lst : rexpr
- | ind_lst ',' rexpr
- ;
-
- for_step : /* empty */
- { bundle(3,_icon,(long)0); }
- | STEP rexpr
- ;
-
- if_else : /* empty */
- {
- i = lpop(&ifstk);
- sprintf(s,"IF%d",i);
- bundle(2,_dlabel,gvadr(s,T_LBL));
- sprintf(s,"IF%d",i+1);
- bundle(2,_dlabel,gvadr(s,T_LBL));
- }
- | ELSE
- {
- i = ltop(&ifstk);
- sprintf(s,"IF%d",i);
- bundle(2,_dlabel,gvadr(s,T_LBL));
- }
- stat
- {
- i = lpop(&ifstk);
- sprintf(s,"IF%d",i+1);
- bundle(2,_dlabel,gvadr(s,T_LBL));
- }
- ;
-
-
- pe : sexpr ','
- { bundle(3,_scon,"",_comma); }
- | sexpr ';'
- | sexpr
- { bundle(3,_scon,"\\n",_scolon); }
- | /* empty */
- { bundle(2,_scon,"\\n"); }
- ;
-
-
- var_lst : ivar
- | rvar
- | svar
- | var_lst ',' var_lst
- ;
-
- sexpr : SCONST
- { p=myalloc(yyleng); strcpy(p,$1); bundle(2,_scon,p); }
- | svar
- { bundle(2,_val,T_CHR); }
- | rexpr
- { bundle(1,_rtoa); }
- | svar '=' sexpr
- { bundle(2,_store,T_CHR); }
- | sexpr ';' sexpr
- { bundle(1,_scolon); }
- | sexpr '+' sexpr
- { bundle(1,_scolon); }
- | sexpr ',' sexpr
- { bundle(1,_comma); }
- | '(' sexpr ')'
- ;
- sbe : sexpr EQUAL sexpr
- { bundle(1,_seq); }
- | sexpr NEQ sexpr
- { bundle(1,_sneq); }
- | sexpr LE sexpr
- { bundle(1,_sleq); }
- | sexpr LT sexpr
- { bundle(1,_slt); }
- | sexpr GE sexpr
- { bundle(1,_sgeq); }
- | sexpr GT sexpr
- { bundle(1,_sgt); }
- ;
-
- ivar : IWORD
- { bundle(2,_var,gvadr($1,T_INT)); }
- | IWORD '('
- { bundle(2,_pushstate,M_EXECUTE); }
- ind_lst ')'
- { bundle(3,_popstate,_var,gvadr($1,T_INT+Q_ARY)); }
- ;
- rvar : RWORD
- { bundle(2,_var,gvadr($1,T_DBL)); }
- | RWORD '('
- { bundle(2,_pushstate,M_EXECUTE); }
- ind_lst ')'
- { bundle(3,_popstate,_var,gvadr($1,T_DBL+Q_ARY)); }
- ;
-
- svar : SWORD
- { bundle(2,_var,gvadr($1,T_CHR)); }
- | SWORD '('
- { bundle(2,_pushstate,M_EXECUTE); }
- ind_lst ')'
- { bundle(3,_popstate,_var,gvadr($1,T_CHR+Q_ARY)); }
- ;
-
-
-
- rexpr : rvar
- { bundle(2,_val,T_DBL); }
- | REAL
- { bundle(5,_rcon,(double)atof($1)); }
- | INTEGER
- { bundle(5,_rcon,(double)atof($1)); }
- | ivar
- { bundle(3,_val,T_INT,_itor); }
- | rvar '=' rexpr
- { bundle(2,_store,T_DBL); }
- | '(' rexpr ')'
- | rexpr '+' rexpr
- { bundle(1,_radd); }
- | rexpr '-' rexpr
- { bundle(1,_rsub); }
- | rexpr '*' rexpr
- { bundle(1,_rmult); }
- | rexpr '/' rexpr
- { bundle(1,_rdiv); }
- | '+' rexpr %prec UNARY
- | '-' rexpr %prec UNARY
- { bundle(6,_rcon,(double)(-1),_rmult); }
- ;
-
- rbe : rexpr EQUAL rexpr
- { bundle(1,_req); }
- | rexpr NEQ rexpr
- { bundle(1,_rneq); }
- | rexpr LE rexpr
- { bundle(1,_rleq); }
- | rexpr LT rexpr
- { bundle(1,_rlt); }
- | rexpr GE rexpr
- { bundle(1,_rgeq); }
- | rexpr GT rexpr
- { bundle(1,_rgt); }
- ;
- bexpr : sbe
- | rbe
- | NOT bexpr %prec UNARY
- { bundle(1,_not); }
- | bexpr OR bexpr
- { bundle(1,_or); }
- | bexpr AND bexpr
- { bundle(1,_and); }
- | '(' bexpr ')'
- ;
- %%
-
- main()
- {
- rdlin(bsin);
- return(yyparse());
- }
-
- yyerror(s)
- char *s;
- {
- fprintf(stderr,"%s\n",s);
- }
-
- lpush(stack,val) struct stk *stack; int val;
- {
- stack->stack[stack->stkp++] = val;
- }
-
- int ltop(stack) struct stk *stack;
- {
- return(stack->stack[stack->stkp-1]);
- }
-
- int lpop(stack) struct stk *stack;
- {
- return(stack->stack[--stack->stkp]);
- }
-
- /* bundle() -- append argument list to l[]. Idea tooken from bc.y.
- *
- * Usage: bundle(cnt,arg,arg,...,arg)
- *
- * The "arg"'s can be anything. "cnt" is a count of the number of integers
- * it would take to hold all the args.
- *
- * e.g. bundle(4,(double)a); is the correct count for a.
- *
- * ******* NOTE *******
- *
- * This routine is machine dependant. It depends on the way arguments are
- * passed on the stack on the PDP-11 machines. It may not work elsewhere.
- */
- bundle(a)
- int a;
- {
- register int *p;
- register int sz;
-
- p = &a;
- sz = *p++;
- while(sz-- > 0)
- l[lp++] = *p++;
- }
- SHAR_EOF
- if test 8891 -ne "`wc -c < 'newbs/bsgram.y'`"
- then
- echo shar: error transmitting "'newbs/bsgram.y'" '(should have been 8891 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'newbs/bslash.c'" '(567 characters)'
- if test -f 'newbs/bslash.c'
- then
- echo shar: will not over-write existing file "'newbs/bslash.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'newbs/bslash.c'
- /* bslash() -- have seen '\', use input() to say what is actually wanted.
- */
- char bslash()
- {
- char text[8];
- register char *s,c;
- int v;
-
- c=input();
- if(c == 'n') c='\n';
- else if(c == 't') c='\t';
- else if(c == 'b') c='\b';
- else if(c == 'r') c='\r';
- else if(c == 'f') c='\f';
- else if(c>='0' && c<='7') { /* octal digit string */
- s = &text[0];
- *s++ = c;
- c=input();
- while(c>='0' && c<='7') {
- *s++ = c;
- c=input();
- }
- *s++ = '\0';
- sscanf(text,"%o",&v);
- c = (char) v;
- }
- else if(c=='\n') rdlin(bsin);
- return(c);
- }
- SHAR_EOF
- if test 567 -ne "`wc -c < 'newbs/bslash.c'`"
- then
- echo shar: error transmitting "'newbs/bslash.c'" '(should have been 567 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'newbs/bslib.c'" '(1553 characters)'
- if test -f 'newbs/bslib.c'
- then
- echo shar: will not over-write existing file "'newbs/bslib.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'newbs/bslib.c'
- /* bslib.c -- subroutine library, routines useful anywhere.
- */
-
- #include "bsdefs.h"
-
- XFILE *bsin = stdin;
-
- /* blcpy -- copies a block of memory (l bytes) from s to d.
- */
- blcpy(d,s,l)
- char *d,*s;
- int l;
- {
- for(; l >= 0; (l--)) *(d++) = *(s++);
- }
-
- /* Input routines. These routines buffer input a line at a time into
- * ibuf. Unputted input goes to pbbuf, and gets read before things in
- * ibuf, if anything in pbbuf.
- */
-
- char pbbuf[CSTKSIZ],ibuf[BFSIZ];
-
- int iptr = -1;
- int pbptr = -1;
-
- char input()
- {
- if(pbptr > -1)
- return(pbbuf[pbptr--]);
- else {
- if(ibuf[iptr] == '\0') rdlin(bsin);
- if(ibuf[iptr]!='\0' && !feof(bsin))
- return(ibuf[iptr++]);
- else
- return(0);
- }
- }
-
- rdlin(f) FILE *f;
- {
- char c;
-
- iptr = 0;
- for(c=fgetc(f); c!='\n' && c!=EOF; c=fgetc(f)) ibuf[iptr++] = c;
- ibuf[iptr++] = c;
- ibuf[iptr++] = '\0';
- iptr = 0;
- }
-
- unput(c) char c;
- { pbbuf[++pbptr] = c; }
-
- /* myalloc() -- allocate, checking for out of memory.
- */
- char *myalloc(nb)
- int nb;
- {
- char *rval;
- rval = malloc(nb);
- /*
- printf("myalloc:tos:%o,rv:%o,nb:%d,e:%o\n",&rval,rval,nb,sbrk(0));
- */
- if(rval == 0) {
- fprintf(stderr,"myalloc: out of memory\n");
- exit(1);
- }
- return(rval);
- }
-
-
-
- /* Stack routines. Very simple. */
-
- union value stack[STKSIZ];
- int stackp = -1;
-
- push(i) union value i;
- {
- stack[++stackp] = i;
- }
-
- union value pop()
- {
- return(stack[stackp--]);
- }
-
- /* Mark stack. Also very simple. */
- int mstack[5];
- int mstkp = -1;
- mpush()
- { mstack[++mstkp] = stackp; }
- mpop()
- { stackp = mstack[mstkp--]; }
- SHAR_EOF
- if test 1553 -ne "`wc -c < 'newbs/bslib.c'`"
- then
- echo shar: error transmitting "'newbs/bslib.c'" '(should have been 1553 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'newbs/getplace.c'" '(488 characters)'
- if test -f 'newbs/getplace.c'
- then
- echo shar: will not over-write existing file "'newbs/getplace.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'newbs/getplace.c'
- /* getplace() -- get a pointer to place of value for vlist entry on top of stack
- * For arrays, getplace() expects the indexes to be on the stack as well.
- * The parser should properly arrange for this to happen.
- */
- union value *getplace(dp)
- struct dictnode *dp;
- {
- int qual;
- union value ind,*place;
-
- qual = dp->type_of_value&T_QMASK;
- if(qual == Q_ARY) {
- ind = pop();
- mpop();
- place = & dp->val.arval[ind.ival+2];
- }
- else
- place = & dp->val;
- return(place);
- }
- SHAR_EOF
- if test 488 -ne "`wc -c < 'newbs/getplace.c'`"
- then
- echo shar: error transmitting "'newbs/getplace.c'" '(should have been 488 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'newbs/gvadr.c'" '(911 characters)'
- if test -f 'newbs/gvadr.c'
- then
- echo shar: will not over-write existing file "'newbs/gvadr.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'newbs/gvadr.c'
- /* gvadr() -- Get variable address from vlist, with type checking.
- * This routine allows numerous copies of same name as long as
- * all copies have different types. Probably doesnt matter since
- * the parser does the type checking.
- */
- struct dictnode *gvadr(s,ty)
- char *s;
- int ty;
- {
- register int i;
- register int qual; /* type qualifier */
-
- /* Inefficient */
- for(i=0; vlist[i].name!=0 && i<VLSIZ; i++)
- if(vlist[i].type_of_value==ty && strcmp(s,vlist[i].name)==0)
- /* match found */
- break;
- if(i >= VLSIZ) {
- fprintf(stderr,"gvadr: out of room in variable list for %s\n",s);
- exit(1);
- }
- /* not on list, enter it */
- if(vlist[i].name == 0) {
- vlist[i].name = myalloc(strlen(s)+1);
- strcpy(vlist[i].name,s);
- vlist[i].val.rval = 0;
- vlist[i].type_of_value = ty;
- if(ty&T_QMASK == Q_ARY)
- vlist[i].val.arval = myalloc(13*sizeof(union value));
- }
- return(&vlist[i]);
- }
- SHAR_EOF
- if test 911 -ne "`wc -c < 'newbs/gvadr.c'`"
- then
- echo shar: error transmitting "'newbs/gvadr.c'" '(should have been 911 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'newbs/makefile'" '(193 characters)'
- if test -f 'newbs/makefile'
- then
- echo shar: will not over-write existing file "'newbs/makefile'"
- else
- sed 's/^X//' << \SHAR_EOF > 'newbs/makefile'
- operat2.o: mkop.sh op rop sop
- mkop.sh >operat2.c
- cc -c operat2.c
- rm operat2.c
- : done operat2.o
- op: mkop.c
- cc mkop.c -o op
- rop: mkrbop.c
- cc mkrbop.c -o rop
- sop: mksop.c
- cc mksop.c -o sop
- SHAR_EOF
- if test 193 -ne "`wc -c < 'newbs/makefile'`"
- then
- echo shar: error transmitting "'newbs/makefile'" '(should have been 193 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'newbs/makefile.old'" '(661 characters)'
- if test -f 'newbs/makefile.old'
- then
- echo shar: will not over-write existing file "'newbs/makefile.old'"
- else
- sed 's/^X//' << \SHAR_EOF > 'newbs/makefile.old'
- OFILES = lex.o bsint.o action.o operat.o bslib.o errors.o
- PRSO= bsgram.o lex.o bslib.o
- INTO= bsint.o action.o operat2.o operat.o bslib.o errors.o
-
- prs: ${PRSO}
- cc -s ${PRSO} -o prs
- bsgram.o: bsgram.c bsdefs.h
- cc -c bsgram.c
- bsgram.c: bsgram.y
- yacc -d bsgram.y
- mv y.tab.c bsgram.c
- mv y.tab.h bstokens.h
-
- int: ${INTO}
- cc ${INTO} -o int
-
- ${OFILES}: bsdefs.h
-
- operat2.o: mkop.sh op rop sop
- mkop.sh >operat2.c
- cc -c operat2.c
- rm operat2.c
- : done operat2.o
- op: mkop.c
- cc mkop.c -o op
- rop: mkrbop.c
- cc mkrbop.c -o rop
- sop: mksop.c
- cc mksop.c -o sop
-
- pr:
- pr bsgram.y lex.c bsdefs.h bslib.c bsint.c action.c operat.c mkop.c mkrbop.c mksop.c errors.c | lpr
- SHAR_EOF
- if test 661 -ne "`wc -c < 'newbs/makefile.old'`"
- then
- echo shar: error transmitting "'newbs/makefile.old'" '(should have been 661 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'newbs/mkop.c'" '(1030 characters)'
- if test -f 'newbs/mkop.c'
- then
- echo shar: will not over-write existing file "'newbs/mkop.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'newbs/mkop.c'
- /* mkop.c -- make operator function for bs.
- *
- * USAGE: op name type oper tag
- *
- * where: name: name of function generated.
- * type: data type of operation.
- * oper: operator for operation.
- * tag: structure tag name.
- *
- * This will only work with T_INT and T_DBL operators, T_CHR operations
- * do not boil down to a simple operation.
- */
- #include <stdio.h>
-
- main(argc,argv)
- char **argv;
- int argc;
- {
- char *name,*type,*oper,*tag;
-
- if(argc != 5) {
- fprintf(stderr,"arg count\n");
- exit(1);
- }
- name = argv[1]; type = argv[2]; oper = argv[3]; tag = argv[4];
-
- printf("_%s(l,p)\n",name);
- printf("int (*l[])(),p;\n");
- printf("{\n");
- printf(" union value rg1,rg2,result;\n");
- printf("\n");
- printf(" if((status&XMODE)==M_READ){ dtype=T_%s; goto EXEC;}\n",type);
- printf(" if((status&XMODE) == M_EXECUTE) {\n");
- printf("EXEC:\n");
- printf(" rg2 = pop();\n");
- printf(" rg1 = pop();\n");
- printf(" result.%s = rg1.%s %s rg2.%s;\n",tag,tag,oper,tag);
- printf(" push(result);\n");
- printf(" }\n");
- printf(" return(p);\n");
- printf("}\n");
- }
- SHAR_EOF
- if test 1030 -ne "`wc -c < 'newbs/mkop.c'`"
- then
- echo shar: error transmitting "'newbs/mkop.c'" '(should have been 1030 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'newbs/mkop.sh'" '(482 characters)'
- if test -f 'newbs/mkop.sh'
- then
- echo shar: will not over-write existing file "'newbs/mkop.sh'"
- else
- sed 's/^X//' << \SHAR_EOF > 'newbs/mkop.sh'
- echo "/* operat2.c -- more operators for bs. the ones that are all alike."
- echo " */"
- echo ""
- echo "#include \"bsdefs.h\""
- echo ""
- op "radd" "DBL" "+" "rval"
- op "rsub" "DBL" "-" "rval"
- op "rmult" "DBL" "*" "rval"
- op "rdiv" "DBL" "/" "rval"
- rop "req" "=="
- sop "seq" "=="
- rop "rneq" "!="
- sop "sneq" "!="
- rop "rleq" "<="
- sop "sleq" "<="
- rop "rlt" "<"
- sop "slt" "<"
- rop "rgeq" ">="
- sop "sgeq" ">="
- rop "rgt" ">"
- sop "sgt" ">"
- op "or" "INT" "||" "ival"
- op "and" "INT" "&&" "ival"
- SHAR_EOF
- if test 482 -ne "`wc -c < 'newbs/mkop.sh'`"
- then
- echo shar: error transmitting "'newbs/mkop.sh'" '(should have been 482 characters)'
- fi
- chmod +x 'newbs/mkop.sh'
- fi # end of overwriting check
- echo shar: extracting "'newbs/mksop.c'" '(725 characters)'
- if test -f 'newbs/mksop.c'
- then
- echo shar: will not over-write existing file "'newbs/mksop.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'newbs/mksop.c'
- /* mksop.c -- make string comparator functions for bs.
- *
- * USAGE: op name oper
- *
- * where: name: name of function generated.
- * oper: operator for operation.
- */
- #include <stdio.h>
-
- main(argc,argv)
- char **argv;
- int argc;
- {
- char *name,*oper;
-
- if(argc != 3) {
- fprintf(stderr,"arg count\n");
- exit(1);
- }
- name = argv[1]; oper = argv[2];
-
- printf("_%s(l,p)\n",name);
- printf("int (*l[])(),p;\n");
- printf("{\n");
- printf(" union value rg1,rg2,result;\n");
- printf("\n");
- printf(" if((status&XMODE) == M_EXECUTE) {\n");
- printf(" rg2 = pop();\n");
- printf(" rg1 = pop();\n");
- printf(" result.sval = strcmp(rg1.sval,rg2.sval) %s 0;\n",oper);
- printf(" push(result);\n");
- printf(" }\n");
- printf(" return(p);\n");
- printf("}\n");
- }
- SHAR_EOF
- if test 725 -ne "`wc -c < 'newbs/mksop.c'`"
- then
- echo shar: error transmitting "'newbs/mksop.c'" '(should have been 725 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'newbs/num_ins.c'" '(3393 characters)'
- if test -f 'newbs/num_ins.c'
- then
- echo shar: will not over-write existing file "'newbs/num_ins.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'newbs/num_ins.c'
- /* int_in() -- tokenizer routine for inputting a number.
- * int_in() returns a pointer to a static data area. This area gets
- * overwritten with each call to int_in so use the data before calling
- * int_in() again.
- */
- char * int_in()
- {
- register char c,*s;
- static char text[20];
-
- s = &text[0];
-
- /* beginning state, skip junk until either '-' or ['0'-'9'] comes along */
-
- l1: c=input();
- if(c>='0' && c<='9') goto l3;
- else if(c == '-') goto l2;
- else {
- if(c=='\n' || c=='\0') rdlin(bsin);
- goto l1;
- }
-
- /* skipped junk, seen '-', gather it and make sure next char is a digit */
-
- l2: *s++ = c;
- c=input();
- if(c==' ' || c=='\t') goto l2; /* allow white between sign and digit */
- else if(c>='0' && c<='9') goto l3;
- else { /* seen something not allowed. */
- s = &text[0];
- printf("\n\007??");
- goto l1; /* restart machine */
- }
-
- /* skipped junk, seen a digit, gather until a non-digit appears */
-
- l3: *s++ = c;
- c=input();
- if(c>='0' && c<='9') goto l3;
- else {
- /* have reached successful conclusion to machine. */
- unput(c);
- *s++ = '\0';
- return(text);
- }
- }
-
- /* real_in() -- read in a floating point number using input().
- *
- * real_in() returns a pointer to a static data area. This data area
- * gets overwritten with each call to real_in(), so use it quickly.
- */
- char *real_in()
- {
- register char *s,c;
- static char bf[30];
-
- s = &bf[0];
-
- /* starting state. loops back until something interesting seen */
-
- state1: c=input();
- if(c == '-') goto state3;
- else if(c>='0' && c<='9') goto state2;
- else if(c == '.') goto state4;
- else {
- if(c == '\0') return(0);
- /* else */
- if(c == '\n') rdlin(bsin);
- goto state1;
- }
-
- /* seen ([sign] dig). loop back for digs, looking for (.|e|E) */
-
- state2: *s++ = c;
- c=input();
- if(c>='0' && c<='9') goto state2;
- else if(c=='e' || c=='E') goto state6;
- else if(c == '.') goto state4;
- else goto state9; /* done */
-
- /* seen (sign). looking for (dig). ignore whitespace. */
-
- state3: *s++ = c;
- state3_a: c=input();
- if(c==' ' || c=='\t') goto state3_a;
- else if(c>='0' && c<='9') goto state2;
- else if(c == '.') goto state4;
- else goto state10; /* error, had a sign so we have to have digs. */
-
- /* seen ([sign] digs '.'). looking for digs. done on anything else */
-
- state4: *s++ = c;
- c=input();
- if(c>='0' && c<='9') goto state5;
- else goto state9; /* done */
-
- /* seen ([sign] digs '.' dig). looking for (dig|e|E). done on anything else */
-
- state5: *s++ = c;
- c=input();
- if(c=='e' || c=='E') goto state6;
- else if(c>='0' && c<='9') goto state5;
- else goto state9;
-
- /* seen ([sign] digs '.' digs (e|E)). looking for sign or digs, else error. */
-
- state6: *s++ = c;
- c=input();
- if(c=='+' || c=='-') goto state7;
- else if(c>='0' && c<='9') goto state8;
- else goto state10; /* error */
-
- /* seen ([sign] digs '.' digs (e|E) sign). looking for digs, else error. */
-
- state7: *s++ = c;
- c=input();
- if(c>='0' && c<='9') goto state8;
- else goto state10; /* error */
-
- /* seen ([sign] digs '.' digs (e|E) [sign] dig). looking for digs. */
-
- state8: *s++ = c;
- c=input();
- if(c>='0' && c<='9') goto state8;
- else goto state9; /* done */
-
- /* seen a complete number. machine successfully completed. whew! */
-
- state9: unput(c); /* might want that later */
- *s++ = '\0';
- return(bf);
-
- /* Uh oh. An error. Print an error and restart. */
-
- state10: printf("\n\007??");
- s = &bf[0];
- goto state1;
- }
- SHAR_EOF
- if test 3393 -ne "`wc -c < 'newbs/num_ins.c'`"
- then
- echo shar: error transmitting "'newbs/num_ins.c'" '(should have been 3393 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'newbs/op2.c'" '(4171 characters)'
- if test -f 'newbs/op2.c'
- then
- echo shar: will not over-write existing file "'newbs/op2.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'newbs/op2.c'
- /* operat2.c -- more operators for bs. the ones that are all alike.
- */
-
- #include "bsdefs.h"
-
- _radd(l,p)
- int (*l[])(),p;
- {
- union value rg1,rg2,result;
-
- if((status&XMODE)==M_READ){ dtype=T_DBL; goto EXEC;}
- if((status&XMODE) == M_EXECUTE) {
- EXEC:
- rg2 = pop();
- rg1 = pop();
- result.rval = rg1.rval + rg2.rval;
- push(result);
- }
- return(p);
- }
- _rsub(l,p)
- int (*l[])(),p;
- {
- union value rg1,rg2,result;
-
- if((status&XMODE)==M_READ){ dtype=T_DBL; goto EXEC;}
- if((status&XMODE) == M_EXECUTE) {
- EXEC:
- rg2 = pop();
- rg1 = pop();
- result.rval = rg1.rval - rg2.rval;
- push(result);
- }
- return(p);
- }
- _rmult(l,p)
- int (*l[])(),p;
- {
- union value rg1,rg2,result;
-
- if((status&XMODE)==M_READ){ dtype=T_DBL; goto EXEC;}
- if((status&XMODE) == M_EXECUTE) {
- EXEC:
- rg2 = pop();
- rg1 = pop();
- result.rval = rg1.rval * rg2.rval;
- push(result);
- }
- return(p);
- }
- _rdiv(l,p)
- int (*l[])(),p;
- {
- union value rg1,rg2,result;
-
- if((status&XMODE)==M_READ){ dtype=T_DBL; goto EXEC;}
- if((status&XMODE) == M_EXECUTE) {
- EXEC:
- rg2 = pop();
- rg1 = pop();
- result.rval = rg1.rval / rg2.rval;
- push(result);
- }
- return(p);
- }
- _req(l,p)
- int (*l[])(),p;
- {
- union value rg1,rg2,result;
-
- if((status&XMODE) == M_EXECUTE) {
- rg2 = pop();
- rg1 = pop();
- result.ival = rg1.rval == rg2.rval;
- push(result);
- }
- return(p);
- }
- _seq(l,p)
- int (*l[])(),p;
- {
- union value rg1,rg2,result;
-
- if((status&XMODE) == M_EXECUTE) {
- rg2 = pop();
- rg1 = pop();
- result.sval = strcmp(rg1.sval,rg2.sval) == 0;
- push(result);
- }
- return(p);
- }
- _rneq(l,p)
- int (*l[])(),p;
- {
- union value rg1,rg2,result;
-
- if((status&XMODE) == M_EXECUTE) {
- rg2 = pop();
- rg1 = pop();
- result.ival = rg1.rval != rg2.rval;
- push(result);
- }
- return(p);
- }
- _sneq(l,p)
- int (*l[])(),p;
- {
- union value rg1,rg2,result;
-
- if((status&XMODE) == M_EXECUTE) {
- rg2 = pop();
- rg1 = pop();
- result.sval = strcmp(rg1.sval,rg2.sval) != 0;
- push(result);
- }
- return(p);
- }
- _rleq(l,p)
- int (*l[])(),p;
- {
- union value rg1,rg2,result;
-
- if((status&XMODE) == M_EXECUTE) {
- rg2 = pop();
- rg1 = pop();
- result.ival = rg1.rval <= rg2.rval;
- push(result);
- }
- return(p);
- }
- _sleq(l,p)
- int (*l[])(),p;
- {
- union value rg1,rg2,result;
-
- if((status&XMODE) == M_EXECUTE) {
- rg2 = pop();
- rg1 = pop();
- result.sval = strcmp(rg1.sval,rg2.sval) <= 0;
- push(result);
- }
- return(p);
- }
- _rlt(l,p)
- int (*l[])(),p;
- {
- union value rg1,rg2,result;
-
- if((status&XMODE) == M_EXECUTE) {
- rg2 = pop();
- rg1 = pop();
- result.ival = rg1.rval < rg2.rval;
- push(result);
- }
- return(p);
- }
- _slt(l,p)
- int (*l[])(),p;
- {
- union value rg1,rg2,result;
-
- if((status&XMODE) == M_EXECUTE) {
- rg2 = pop();
- rg1 = pop();
- result.sval = strcmp(rg1.sval,rg2.sval) < 0;
- push(result);
- }
- return(p);
- }
- _rgeq(l,p)
- int (*l[])(),p;
- {
- union value rg1,rg2,result;
-
- if((status&XMODE) == M_EXECUTE) {
- rg2 = pop();
- rg1 = pop();
- result.ival = rg1.rval >= rg2.rval;
- push(result);
- }
- return(p);
- }
- _sgeq(l,p)
- int (*l[])(),p;
- {
- union value rg1,rg2,result;
-
- if((status&XMODE) == M_EXECUTE) {
- rg2 = pop();
- rg1 = pop();
- result.sval = strcmp(rg1.sval,rg2.sval) >= 0;
- push(result);
- }
- return(p);
- }
- _rgt(l,p)
- int (*l[])(),p;
- {
- union value rg1,rg2,result;
-
- if((status&XMODE) == M_EXECUTE) {
- rg2 = pop();
- rg1 = pop();
- result.ival = rg1.rval > rg2.rval;
- push(result);
- }
- return(p);
- }
- _sgt(l,p)
- int (*l[])(),p;
- {
- union value rg1,rg2,result;
-
- if((status&XMODE) == M_EXECUTE) {
- rg2 = pop();
- rg1 = pop();
- result.sval = strcmp(rg1.sval,rg2.sval) > 0;
- push(result);
- }
- return(p);
- }
- _or(l,p)
- int (*l[])(),p;
- {
- union value rg1,rg2,result;
-
- if((status&XMODE)==M_READ){ dtype=T_INT; goto EXEC;}
- if((status&XMODE) == M_EXECUTE) {
- EXEC:
- rg2 = pop();
- rg1 = pop();
- result.ival = rg1.ival || rg2.ival;
- push(result);
- }
- return(p);
- }
- _and(l,p)
- int (*l[])(),p;
- {
- union value rg1,rg2,result;
-
- if((status&XMODE)==M_READ){ dtype=T_INT; goto EXEC;}
- if((status&XMODE) == M_EXECUTE) {
- EXEC:
- rg2 = pop();
- rg1 = pop();
- result.ival = rg1.ival && rg2.ival;
- push(result);
- }
- return(p);
- }
- SHAR_EOF
- if test 4171 -ne "`wc -c < 'newbs/op2.c'`"
- then
- echo shar: error transmitting "'newbs/op2.c'" '(should have been 4171 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'newbs/operat.c'" '(8663 characters)'
- if test -f 'newbs/operat.c'
- then
- echo shar: will not over-write existing file "'newbs/operat.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'newbs/operat.c'
- /* operat.c -- operations, as opposed to actions. FOR is an action,
- * '+' is an operation.
- *
- * More operators can be found in the machine generated file "operat2.c".
- */
-
- #include "bsdefs.h"
-
-
- /* BINARY OPERATORS */
-
- /* Common description for the binary ops.
- * also applies to all ops in operat2.c
- *
- * M_COMPILE:
- * x op x --to-- x,_op,x
- * M_EXECUTE:
- * stack: ar2,ar1,x --to-- (ar1 op ar2),x
- */
-
-
- _comma(l,p) int (*l[])(),p;
- {
- union value s1,s2,s3;
- if((status&XMODE) == M_FIXUP) return(p);
- if((status&XMODE) == M_READ) { dtype = T_CHR; goto EXEC; }
- if((status&XMODE) == M_EXECUTE) {
- EXEC:
- s1 = pop();
- s2 = pop();
- s3.sval = myalloc(strlen(s1.sval)+strlen(s2.sval)+3);
- strcpy(s3.sval,s2.sval);
- strcat(s3.sval,"\t");
- strcat(s3.sval,s1.sval);
- if(s1.sval != 0) free(s1.sval);
- if(s2.sval != 0) free(s2.sval);
- push(s3);
- }
- return(p);
- }
- _scolon(l,p) int(*l[])(),p;
- {
- union value s1,s2,s3;
- if((status&XMODE) == M_READ) { dtype = T_CHR; goto EXEC; }
- if((status&XMODE) == M_EXECUTE) {
- EXEC:
- s1 = pop();
- s2 = pop();
- s3.sval = myalloc(strlen(s1.sval)+strlen(s2.sval)+2);
- strcpy(s3.sval,s2.sval);
- strcat(s3.sval,s1.sval);
- push(s3);
- if(s1.sval != 0) free(s1.sval);
- if(s2.sval != 0) free(s2.sval);
- }
- return(p);
- }
- /* last of binary operators */
-
- /* ---And now for something completely different: a Unary Operator.
- *
- * M_COMPILE:
- * x not x --to-- x,_not,x
- * M_EXECUTE:
- * stack: bool,x --to-- !(bool),x
- */
- _not(l,p) int (*l[])(),p;
- {
- union value val;
-
- if((status&XMODE) == M_EXECUTE) {
- val = pop();
- val.ival = ! val.ival;
- push(val);
- }
- return(p);
- }
-
- /* M_COMPILE:
- * x itoa x --to-- x,_itoa,x
- * M_EXECUTE:
- * stack: int,x --to-- string,x
- */
- _itoa(l,p)
- int (*l[])(),p;
- {
- union value val;
- char s2[30];
-
- if((status&XMODE) == M_READ) { dtype = T_CHR; goto EXEC; }
- if((status&XMODE) == M_EXECUTE) {
- EXEC:
- val=pop();
- sprintf(s2,"%D",val.ival); /* optimize later */
- if(dbg) printf("_icon():M_EXECUTE:ival:%D to sval:%s\n",val.ival,s2);
- val.sval=myalloc(strlen(s2)+1);
- strcpy(val.sval,s2);
- push(val);
- }
- return(p);
- }
- _rtoa(l,p)
- int (*l[])(),p;
- {
- union value val;
- char s2[30];
-
- if((status&XMODE) == M_READ) { dtype = T_CHR; goto EXEC; }
- if((status&XMODE) == M_EXECUTE) {
- EXEC:
- val = pop();
- sprintf(s2,"%g",val.rval);
- if(dbg) printf("_rtoa():M_EXECUTE:rval:%g to sval:%s\n",val.rval,s2);
- val.sval = myalloc(strlen(s2)+1);
- strcpy(val.sval,s2);
- push(val);
- }
- return(p);
- }
- _itor(l,p)
- int (*l[])(),p;
- {
- union value v1,v2;
-
- if((status&XMODE) == M_READ) { dtype = T_DBL; goto EXEC; }
- if((status&XMODE) == M_EXECUTE) {
- EXEC:
- v1 = pop();
- v2.rval = (double)v1.ival;
- push(v2);
- }
- return(p);
- }
- _rtoi(l,p)
- int (*l[])(),p;
- {
- union value v1,v2;
-
- if((status&XMODE) == M_READ) { dtype = T_INT; goto EXEC; }
- if((status&XMODE) == M_EXECUTE) {
- EXEC:
- v1 = pop();
- v2.ival = (int)v1.rval;
- push(v2);
- }
- return(p);
- }
-
- /* M_COMPILE:
- * x scon "quoted string" x --to-- x,_scon,&string,x
- * M_EXECUTE:
- * stack: x --to-- string,x
- * other: pushes a COPY of the string, not the original.
- */
- _scon(l,p)
- int (*l[])(),p;
- {
- char *s,c;
- union value val;
- int i;
-
- if((status&XMODE) == M_FIXUP) ++p;
- if((status&XMODE) == M_READ) { dtype = T_CHR; goto EXEC; }
- if((status&XMODE) == M_EXECUTE) {
- EXEC:
- s = l[p++];
- val.sval = myalloc(strlen(s)+1);
- strcpy(val.sval,s);
- push(val);
- if(dbg) printf("_scon():M_EXECUTE:sval:%s\n",val.sval);
- }
- return(p);
- }
-
- /* M_COMPILE:
- * x icon int x --to-- x,_icon,int,x
- * M_EXECUTE:
- * stack: x --to-- int,x
- */
- _icon(l,p)
- int (*l[])(),p;
- {
- union value val;
- union loni v;
- int i;
-
- if((status&XMODE) == M_FIXUP) return(p+(sizeof(long)/sizeof(int)));
- if((status&XMODE) == M_READ) { dtype = T_INT; goto EXEC; }
- if((status&XMODE) == M_EXECUTE) {
- EXEC:
- for(i=0; i<(sizeof(long)/sizeof(int)); i++)
- v.i_in_loni[i] = l[p++];
- val.ival = v.l_in_loni;
- push(val);
- if(dbg) printf("_icon():M_EXECUTE:ival:%D\n",val.ival);
- }
- return(p);
- }
- _rcon(l,p)
- int (*l[])(),p;
- {
- union doni v;
- int i;
- union value val;
-
- if((status&XMODE) == M_FIXUP) return(p+(sizeof(double)/sizeof(int)));
- if((status&XMODE) == M_READ) { dtype = T_DBL; goto EXEC; }
- if((status&XMODE) = M_EXECUTE) {
- EXEC:
- for(i=0; i<(sizeof(double)/sizeof(int)); i++)
- v.i_in_doni[i] = l[p++];
- val.rval = v.d_in_doni;
- push(val);
- }
- return(p);
- }
-
- /* M_COMPILE:
- * x val type x --to-- x,_val,type,x
- * M_EXECUTE:
- * stack: place,x --to-- value,x
- * other: for strings, pushes a copy of the string.
- */
- _val(l,p) int(*l[])(),p;
- {
- union value place,val;
- int ty;
-
- if((status&XMODE) == M_READ) { dtype = l[p]; goto EXEC; }
- if((status&XMODE) == M_EXECUTE) {
- EXEC:
- ty = l[p];
- place = pop();
- if(dbg) printf("_val():M_EXECUTE:var:%s",place.vpval->name);
- place.plval = getplace(place.vpval);
- if(ty==T_CHR && place.plval->sval!=0) {
- val.sval = myalloc(strlen(place.plval->sval)+1);
- strcpy(val.sval,place.plval->sval);
- push(val);
- }
- else push(*place.plval);
- if(dbg) printf(":ival:%D:rval:%g:sval:%s\n",ty==T_INT?place.plval->ival:(long)0,
- ty==T_DBL?place.plval->rval:(double)0,ty==T_CHR?place.plval->sval:0);
- }
- return(p+1);
- }
-
- /* M_COMPILE:
- * x store typ x --to-- x,_store,type,x
- * M_EXECUTE:
- * stack: value,location,x --to-- value,x
- * (stores value at location).
- */
- _store(l,p) int(*l[])(),p;
- {
- union value place,val;
- int ty;
-
- if((status&XMODE) == M_READ) { dtype = l[p]; goto EXEC; }
- if((status&XMODE) == M_EXECUTE) {
- EXEC:
- val = pop();
- place = pop();
- ty = l[p];
- if(dbg) printf("_store():M_EXECUTE:var:%s:ival:%D:rval:%g:sval:%s\n",
- place.vpval->name,ty==T_INT?val.ival:(long)0,ty==T_DBL?val.rval:(double)0,ty==T_CHR?val.sval:0);
- place.plval = getplace(place.vpval);
- if(ty==T_CHR && place.plval->sval!=0) free(place.plval->sval);
- (*place.plval) = val;
- push(val);
- }
- return(p+1);
- }
-
- /* M_COMPILE:
- * x var typ name x --to-- x,_var,&vlist entry,x
- * M_EXECUTE:
- * stack: x --to-- &vlist entry,x
- * M_INPUT:
- * (&vlist entry)->val is set to input value.
- * M_READ:
- * Moves the data list pointers to the next data item. If no next
- * data item, calls ODerror.
- * Does a "gosub" to the data item, to get its value on the stack.
- * Does T_INT to T_CHR conversion if necessary.
- * Pops value into vp->val.
- */
- _var(l,p) int(*l[])(),p; /* same proc for any variable type */
- {
- char *s;
- struct dictnode *vp;
- struct line *thislist;
- union value place,val;
- int ty,qual;
-
- if((status&XMODE) == M_EXECUTE) {
- val.vpval = l[p++];
- if(dbg) printf("_var():M_EXECUTE:var:(%d)%s\n",val.vpval->type_of_value,
- val.vpval->name);
- push(val);
- return(p);
- }
- if((status&XMODE) == M_INPUT) {
- vp = l[p++];
- place.plval = getplace(vp);
- ty = (vp->type_of_value) & T_TMASK;
- if(ty == T_INT)
- place.plval->ival = atol(int_in());
- else if(ty == T_DBL)
- place.plval->rval = atof(real_in());
- else /* ty == T_CHR */
- place.plval->sval = scon_in();
- if(dbg) printf("_var():M_INPUT:var:(%d)%s:ival:%D:rval:%g:sval:%s\n",
- vp->type_of_value,vp->name,ty==T_INT?place.plval->ival:(long)0,
- ty==T_DBL?place.plval->rval:(double)0,ty==T_CHR?place.plval->sval:0);
- return(p);
- }
- if((status&XMODE) == M_READ) {
- nxdl: if(dlist[dlp] == 0) ODerror(l,p); /* ran off end of dlist */
- thislist = dlist[dlp];
- if((thislist->code)[dlindx] == 0) {
- dlp++;
- dlindx = 2; /* skips <_data,0> */
- goto nxdl;
- }
-
- status = M_EXECUTE;
- dlindx = interp(thislist->code,dlindx);
- status = M_READ;
-
- val = pop();
- vp = l[p];
- place.plval = getplace(vp);
- qual = vp->type_of_value&T_TMASK;
- if(qual == T_INT) {
- if(dtype == T_DBL) {
- push(val); _rtoi(l,p); val = pop();
- }
- place.plval->ival = val.ival;
- }
- else if(qual == T_DBL) {
- if(dtype == T_INT) {
- push(val); _itor(l,p); val = pop();
- }
- place.plval->rval = val.rval;
- }
- else if(qual == T_CHR) {
- if(dtype == T_INT) {
- push(val); _itoa(l,p); val = pop();
- }
- else if(dtype == T_DBL) {
- push(val); _rtoa(l,p); val = pop();
- }
- if(place.plval->sval != 0) free(place.plval->sval);
- place.plval->sval = myalloc(strlen(val.sval)+1);
- strcpy(place.plval->sval,val.sval);
- }
- else VTerror(l,p);
- return(p+1);
- }
- return(p+1);
- }
- SHAR_EOF
- if test 8663 -ne "`wc -c < 'newbs/operat.c'`"
- then
- echo shar: error transmitting "'newbs/operat.c'" '(should have been 8663 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'newbs/scon_in.c'" '(1454 characters)'
- if test -f 'newbs/scon_in.c'
- then
- echo shar: will not over-write existing file "'newbs/scon_in.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'newbs/scon_in.c'
- /* scon_in() -- read in a string constant using input.
- * Format of an scon is either a quoted string, or a sequence
- * of characters ended with a seperator (' ', '\t' or '\n' or ',').
- *
- * In either mode, you can get funny characters into the string by
- * "quoting" them with a '\'.
- *
- * scon_in() uses myalloc() to create space to store the string in.
- */
- char *scon_in()
- {
- register char c,*s;
- static char text [80];
-
- s = &text[0];
-
- /* beginning state, skip seperators until something interesting comes along */
-
- l1: c=input();
- if(c == '"') goto l2;
- else if(c=='\n' || c=='\0') {
- rdlin(bsin);
- goto l1;
- }
- else if(c==' ' || c=='\t' || c==',') goto l1;
- else goto l3;
-
- /* have skipped unwanted material, seen a '"', read in a quoted string */
-
- l2: c=input();
- if(c == '\n') {
- fprintf(stderr,"scon_in: unterminated string\n");
- exit(1);
- }
- else if(c == '\\') { *s++ = bslash(bsin); goto l2; }
- else if(c == '"')
- if((c=input()) == '"') {
- *s++ = '"';
- goto l2;
- }
- else goto done;
- else { *s++ = c; goto l2; }
-
- /* skipped unwanted, seen something interesting, not '"', gather until sep */
-
- l3: *s++ = c;
- c=input();
- if(c == '\\') { c = bslash(bsin); goto l3; }
- else if(c==' ' || c=='\t' || c==',' || c=='\n') goto done;
- else goto l3;
-
- /* final state (if machine finished ok.) */
-
- done: unput(c);
- *s++ = '\0';
- s=myalloc(strlen(text)+1);
- strcpy(s,text);
- return(s);
- }
- SHAR_EOF
- if test 1454 -ne "`wc -c < 'newbs/scon_in.c'`"
- then
- echo shar: error transmitting "'newbs/scon_in.c'" '(should have been 1454 characters)'
- fi
- fi # end of overwriting check
- # End of shell archive
- exit 0
-